package com.pxl.springbootinit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pxl.springbootinit.common.ErrorCode;
import com.pxl.springbootinit.exception.BusinessException;
import com.pxl.springbootinit.model.dto.item.ItemForm;
import com.pxl.springbootinit.model.entity.Item;
import com.pxl.springbootinit.model.entity.User;
import com.pxl.springbootinit.model.enums.AvailableStatusEnum;
import com.pxl.springbootinit.model.enums.ReviewStatusEnum;
import com.pxl.springbootinit.model.vo.ItemVO;
import com.pxl.springbootinit.model.vo.RankVO;
import com.pxl.springbootinit.model.vo.StatisticsItemVO;
import com.pxl.springbootinit.service.ItemService;
import com.pxl.springbootinit.mapper.ItemMapper;
import com.pxl.springbootinit.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
* @author MADAO
* @description 针对表【item(物品信息表)】的数据库操作Service实现
* @createDate 2024-12-20 12:02:23
*/
@Service
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item>
    implements ItemService{

    @Resource
    private UserService userService;
    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    // 发布商品
    @Override
    public Boolean publishItem(ItemForm itemForm) {
        Long userId = itemForm.getUserId();
        if (userId == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户ID不能为空");
        }
        User user = userService.getById(userId);
        if (user.getAddress() == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户地址不能为空");
        }
        Item item = new Item();
        BeanUtils.copyProperties(itemForm, item);
        item.setId(null);
        item.setRegion(user.getAddress());
        item.setStatus(ReviewStatusEnum.PENDING.getValue());
        return this.save(item);
    }

    // 查询商品列表
    @Override
    public Page<ItemVO> itemPage(ItemForm itemForm) {
        int pageSize = itemForm.getPageSize();
        int current = itemForm.getCurrent();
        Page<Item> itemPage = new Page<>(current, pageSize);
        QueryWrapper<Item> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(itemForm.getName()), "name", itemForm.getName());
        queryWrapper.like(StringUtils.isNotBlank(itemForm.getStatus()), "status", itemForm.getStatus());
        queryWrapper.like(StringUtils.isNotBlank(itemForm.getCategory()), "category", itemForm.getCategory());
        queryWrapper.like(StringUtils.isNotBlank(itemForm.getRegion()), "region", itemForm.getRegion());
        queryWrapper.eq(itemForm.getUserId() != null, "user_id", itemForm.getUserId());
        queryWrapper.eq("item_type", AvailableStatusEnum.ACTIVE.getValue());
        queryWrapper.eq("status", ReviewStatusEnum.APPROVED.getValue());
        queryWrapper.orderByDesc("updated_time");
        Page<Item> page = this.page(itemPage, queryWrapper);
        List<ItemVO> collect = page.getRecords().stream()
                .map(item -> getItemVO(item))
                .collect(Collectors.toList());
        Page<ItemVO> itemVOPage = new Page<>();
        itemVOPage.setTotal(page.getTotal());
        itemVOPage.setPages(page.getPages());
        itemVOPage.setRecords(collect);
        return itemVOPage;
    }

    @Override
    public List<String> itemTypes() {
        return this.baseMapper.selectTypes();
    }

    @Override
    public List<String> itemAllTypes() {
        return this.baseMapper.selectAllTypes();
    }

    @Override
    public Boolean updateItem(ItemForm itemForm) {
        if (itemForm.getId() == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"物品ID不能为空");
        }
        Item item = new Item();
        BeanUtils.copyProperties(itemForm, item);
        return this.updateById(item);
    }

    @Override
    public List<RankVO> rank(Integer nums) {
        List<RankVO> rankVOList = this.baseMapper.rank(nums);
        if (rankVOList == null || rankVOList.isEmpty()){
            return new ArrayList<>();
        }
        List<Long> userIdList = new ArrayList<>(rankVOList.size());
        for (RankVO rankVO : rankVOList) {
            userIdList.add(rankVO.getUserId());
        }
        Map<Long, String> userMap = userService.listByIds(userIdList).stream()
                .collect(Collectors.toMap(User::getId, User::getUsername));
        rankVOList.forEach(rankVO -> {
            rankVO.setUsername(userMap.get(rankVO.getUserId()));
        });
        return rankVOList;
    }

    @Override
    public StatisticsItemVO statistics() throws ExecutionException, InterruptedException {
        StatisticsItemVO statisticsItemVO = new StatisticsItemVO();
        // TODO：这个可加入缓存，提高接口响应速度；这里的并排查询为替代方案
        Integer totalDonation = new CompletableFuture<Integer>().completeAsync(() -> this.baseMapper.totalDonation(),threadPoolExecutor).get();
        Integer todayDonation = new CompletableFuture<Integer>().completeAsync(() -> this.baseMapper.todayDonation(),threadPoolExecutor).get();
        Integer totalDonor = new CompletableFuture<Integer>().completeAsync(() -> this.baseMapper.totalDonor(),threadPoolExecutor).get();
        statisticsItemVO.setTotalDonation(totalDonation);
        statisticsItemVO.setTodayDonation(todayDonation);
        statisticsItemVO.setTotalDonor(totalDonor);
        return statisticsItemVO;
    }

    @Override
    public List<String> itemPictures(HttpServletRequest request) throws IOException, URISyntaxException{
        // 获取所有图片文件的URL
        List<String> imageUrls = new ArrayList<>();

        // 获取文件夹路径
        Path folderPath = Paths.get(getClass().getClassLoader().getResource("static/imgs/homePageImg").toURI());

        // 获取协议（http 或 https）
        String protocol = request.getScheme();
        // 获取主机名
        String host = request.getServerName();
        // 获取端口号
        int port = request.getServerPort();

        // 构建基础URL
        String prefix =  protocol + "://" + host + ":" + port + "/api";

        // 获取文件夹下所有文件
        Files.walk(folderPath)
                .filter(Files::isRegularFile)
                .forEach(file -> {
                    String fileName = file.getFileName().toString();
                    String fileUrl = prefix + "/imgs/homePageImg/" + fileName;  // 拼接 URL
                    imageUrls.add(fileUrl);
                });

        return imageUrls;
    }

    @Override
    public ItemVO getItemVO(Item item){
        ItemVO itemVO = new ItemVO();
        BeanUtils.copyProperties(item, itemVO);
        return itemVO;
    }

    @Override
    public Page<ItemVO> adminPage(ItemForm itemForm) {
        int pageSize = itemForm.getPageSize();
        int current = itemForm.getCurrent();
        Page<Item> itemPage = new Page<>(current, pageSize);
        QueryWrapper<Item> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(itemForm.getName()), "name", itemForm.getName());
        queryWrapper.like(StringUtils.isNotBlank(itemForm.getStatus()), "status", itemForm.getStatus());
        queryWrapper.like(StringUtils.isNotBlank(itemForm.getCategory()), "category", itemForm.getCategory());
        queryWrapper.like(StringUtils.isNotBlank(itemForm.getRegion()), "region", itemForm.getRegion());
        queryWrapper.eq(itemForm.getUserId() != null, "user_id", itemForm.getUserId());
        queryWrapper.eq(itemForm.getItemType() != null,"item_type", itemForm.getItemType());
        queryWrapper.orderByDesc("updated_time");
        Page<Item> page = this.page(itemPage, queryWrapper);
        List<ItemVO> collect = page.getRecords().stream()
                .map(item -> getItemVO(item))
                .collect(Collectors.toList());
        Page<ItemVO> itemVOPage = new Page<>();
        itemVOPage.setTotal(page.getTotal());
        itemVOPage.setPages(page.getPages());
        itemVOPage.setRecords(collect);
        return itemVOPage;
    }
}




